#include <input_manager.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
#include <string.h>

pInputDevice g_InputDevs = NULL;

static pthread_cond_t g_tConVar = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t g_tMutex = PTHREAD_MUTEX_INITIALIZER;


/* start of 实现环形buffer */
#define BUFFER_LEN 20
static int g_iRead = 0;
static int g_iWrite = 0;
static InputEvent g_atInputEvents[BUFFER_LEN]; 

static int isInputBufferFull(void)
{
//	if(((g_iWrite + 1) % BUFFER_LEN) == g_iRead)
//	{
//		return 1;
//	}else{
//		return 0;
//	}
	return (((g_iWrite + 1) % BUFFER_LEN) == g_iRead);
}

static int isInputBufferEmpty(void)
{
//	if(g_iWrite == g_iRead)
//	{
//		return 1;
//	}else{
//		return 0;
//	}
	return (g_iWrite == g_iRead);
}

static void PutInputEventToBuffer(pInputEvent ptInputEvent)
{
	if(!isInputBufferFull())
	{
		g_atInputEvents[g_iWrite] = *ptInputEvent;
		g_iWrite = (g_iWrite + 1) % BUFFER_LEN;
	}
}

static int GetInputEventFromBuffer(pInputEvent ptInputEvent)
{
	if(!isInputBufferEmpty())
	{
		*ptInputEvent = g_atInputEvents[g_iRead];
		g_iRead = (g_iRead + 1) % BUFFER_LEN;
		return 1;
	}
	return 0;
}


/* end of 实现环形buffer */

void RegisterInputDevice(pInputDevice ptInputDevice)
{
	ptInputDevice->ptNext = g_InputDevs;
	g_InputDevs = ptInputDevice;
}

void InputSystemRegister(void)
{
	/* register touchscreen */
	RegisterTsDev();
	
	/* register netinput */
	RegisterNetinputDev();
}

static void* input_recv_thread_func (void *data)
{
	pInputDevice ptInputdev = (pInputDevice)data;
	InputEvent tEvent;
	int ret = -1;
    while (1)
    {   
    	/* 获取数据 */
    	ret = ptInputdev->GetInputEvent(&tEvent);
		//如果没问题：
		if(!ret)
		{
			/* 保存数据 */
			pthread_mutex_lock(&g_tMutex);
			PutInputEventToBuffer(&tEvent);
			/* 唤醒其他等待数据的线程 */
			pthread_cond_signal(&g_tConVar);
			pthread_mutex_unlock(&g_tMutex);
		}

    }
    return (void*)-1;
}


void InputDeviceInit(void)
{
	int ret;
	pthread_t tid;
	/* for each inputdevice, init, pthread_create */
	pInputDevice ptCurIndev = g_InputDevs;
	while(ptCurIndev)
	{
		/* init device */
		ret = ptCurIndev->DeviceInit();
		/* pthread create */
		if(ret)
		{
			printf("DeviceInit error!\n");
			ptCurIndev = ptCurIndev->ptNext;
			continue;
		}
		ret = pthread_create(&tid, NULL, input_recv_thread_func, ptCurIndev);
	    if(ret)//失败
	    {
	        printf("pthread_creat error!\n");
	        return;
	    }
		ptCurIndev = ptCurIndev->ptNext;
	}
}

int GetInputEvent(pInputEvent ptInputEvent)
{
	int ret;
	/* 无数据则休眠 */
	pthread_mutex_lock(&g_tMutex);
	if(GetInputEventFromBuffer(ptInputEvent))
	{
		pthread_mutex_unlock(&g_tMutex);
		return 0;
	}else{
		/* 休眠等待 */
		pthread_cond_wait(&g_tConVar,&g_tMutex);
		if(GetInputEventFromBuffer(ptInputEvent))
		{
			ret = 0;
		}else
		{
			ret = -1;
		}
		pthread_mutex_unlock(&g_tMutex);
		/* 返回数据 */
	}
	return ret;
}
